//Promise对象代表一个异步操作，有三种状态：
// Pending（进行中）、Resolved（已完成，又称 Fulfilled）和Rejected（已失败）。
function timeout(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done');
    });
}

// then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用，
// 第二个回调函数是Promise对象的状态变为Reject时调用。
timeout(100).then((value) => { // 成功时调用的方法
    console.log(value);
}, (error) => {//失败时调用的方法
    //
});

//如果Promise状态已经变成Resolved，再抛出错误是无效的
var promise = new Promise(function(resolve, reject) {
    resolve('ok');
    throw new Error('test');
});
promise
    .then(function(value) { console.log(value) })
    .catch(function(error) { console.log(error) });
// ok


//Promise.all方法用于将多个Promise实例，包装成一个新的Promise实例。
//var p = Promise.all([p1, p2, p3]);
//p的状态由p1、p2、p3决定，分成两种情况。
//
// （1）只有p1、p2、p3的状态都变成fulfilled，p的状态才会变成fulfilled，
//      此时p1、p2、p3的返回值组成一个数组，传递给p的回调函数。
//
// （2）只要p1、p2、p3之中有一个被rejected，p的状态就变成rejected，此时第一个
//      被reject的实例的返回值，会传递给p的回调函数。


//var p = Promise.race([p1, p2, p3]);
//只要p1、p2、p3之中有一个实例率先改变状态，p的状态就跟着改变。那个率先改变
// 的 Promise 实例的返回值，就传递给p的回调函数


// 立即resolve的Promise对象，是在本轮“事件循环”（event loop）的结束时，而不是在下一轮“事件循环”的开始时
setTimeout(function () {
    console.log('three');
}, 0);

Promise.resolve().then(function () {
    console.log('two');
});

console.log('one');
// 上面代码中，setTimeout(fn, 0)在下一轮“事件循环”开始时执行，
// Promise.resolve()在本轮“事件循环”结束时执行，console.log(’one‘)则是立即执行，因此最先输出

